package cn.iocoder.yudao.module.system.service.worksaleoutbound;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.format.FastDateFormat;
import cn.iocoder.yudao.module.system.dal.dataobject.workorder.WorkOrderDO;
import cn.iocoder.yudao.module.system.dal.dataobject.workstore.WorkStoreDO;
import cn.iocoder.yudao.module.system.dal.dataobject.workstorepallet.WorkStorePalletDO;
import cn.iocoder.yudao.module.system.dal.mysql.workorder.WorkOrderMapper;
import cn.iocoder.yudao.module.system.dal.mysql.workstore.WorkStoreMapper;
import cn.iocoder.yudao.module.system.dal.mysql.workstorepallet.WorkStorePalletMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.Year;
import java.time.YearMonth;
import java.util.*;
import cn.iocoder.yudao.module.system.controller.admin.worksaleoutbound.vo.*;
import cn.iocoder.yudao.module.system.dal.dataobject.worksaleoutbound.WorkSaleOutboundDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.system.dal.mysql.worksaleoutbound.WorkSaleOutboundMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;

/**
 * 销售出库 Service 实现类
 *
 * @author 超级管理员
 */
@Service
@Validated
public class WorkSaleOutboundServiceImpl implements WorkSaleOutboundService {

    @Resource
    private WorkSaleOutboundMapper workSaleOutboundMapper;
    @Resource
    private WorkStorePalletMapper workStorePalletMapper;
    @Resource
    private WorkStoreMapper workStoreMapper;
    @Resource
    private WorkOrderMapper workOrderMapper;

    @Override
    public String createWorkSaleOutbound(List<WorkSaleOutboundSaveReqVO> createReqVO) {
        UUID uuid = UUID.randomUUID(); // 生成随机UUID
        String batchNumber = uuid.toString();
        // 插入
        List<WorkSaleOutboundDO> workSaleOutbound = BeanUtils.toBean(createReqVO, WorkSaleOutboundDO.class);
        List<Integer> workIds = new ArrayList<>();
        for (WorkSaleOutboundDO item:workSaleOutbound) {
            workIds.add(item.getWorkId());
        }
        List<WorkOrderDO> workOrderDOS = workOrderMapper.selectList(new QueryWrapper<WorkOrderDO>().in("id",workIds));
        for (WorkSaleOutboundDO item:workSaleOutbound) {
            item.setBatchNumber(batchNumber);
            for (WorkOrderDO order:workOrderDOS) {
                if(Long.valueOf(item.getWorkId()).equals(order.getId())){
                    item.setCustomerId(order.getCustomerId());
                    //更新订单信息
                    UpdateWrapper<WorkOrderDO> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.eq("id",item.getWorkId());
                    if(order.getStorageMethod().equals("1")){
                        String sql = "finished_product_num = finished_product_num - "+item.getOutboundQuantity()+",sales_volumes = sales_volumes + "+item.getOutboundQuantity();
                        updateWrapper.setSql(sql);
                    }else{
                        String sql = "finished_product_num = finished_product_num - "+item.getOutboundWeight()+",sales_volumes = sales_volumes + "+item.getOutboundWeight();
                        updateWrapper.setSql(sql);
                    }
                    workOrderMapper.update(updateWrapper);
                    break;
                }
            }
        }
        workSaleOutboundMapper.insertBatch(workSaleOutbound);
        // 返回
        return batchNumber;
    }

    @Override
    public void updateWorkSaleOutbound(WorkSaleOutboundSaveReqVO updateReqVO) {
        // 校验存在
        validateWorkSaleOutboundExists(updateReqVO.getId());
        // 更新
        WorkSaleOutboundDO updateObj = BeanUtils.toBean(updateReqVO, WorkSaleOutboundDO.class);
        workSaleOutboundMapper.updateById(updateObj);
    }

    @Override
    public void deleteWorkSaleOutbound(Integer id) {
        // 校验存在
        validateWorkSaleOutboundExists(id);
        // 删除
        workSaleOutboundMapper.deleteById(id);
    }

    @Override
        public void deleteWorkSaleOutboundListByIds(List<Integer> ids) {
        // 校验存在
        validateWorkSaleOutboundExists(ids);
        // 删除
        workSaleOutboundMapper.deleteByIds(ids);
        }

    private void validateWorkSaleOutboundExists(List<Integer> ids) {
        List<WorkSaleOutboundDO> list = workSaleOutboundMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(WORK_SALE_OUTBOUND_NOT_EXISTS);
        }
    }

    private void validateWorkSaleOutboundExists(Integer id) {
        if (workSaleOutboundMapper.selectById(id) == null) {
            throw exception(WORK_SALE_OUTBOUND_NOT_EXISTS);
        }
    }

    @Override
    public WorkSaleOutboundDO getWorkSaleOutbound(Integer id) {
        return workSaleOutboundMapper.selectById(id);
    }
    @Override
    public WorkSaleODORespVO getODo(String batchNumber) {
        WorkSaleODORespVO data = new WorkSaleODORespVO();
        List<WorkSaleOutboundDO> arr = workSaleOutboundMapper.selectList(new QueryWrapper<WorkSaleOutboundDO>().eq("batch_number",batchNumber));
        List<WorkSaleODODetailRespVO> detailRespVOS = BeanUtils.toBean(arr, WorkSaleODODetailRespVO.class);
        List<Integer> workIds = new ArrayList<>();
        for (WorkSaleODODetailRespVO item:detailRespVOS) {
            workIds.add(item.getWorkId());
        }
        QueryWrapper<WorkStorePalletDO> workStorePalletDOQueryWrapper = new QueryWrapper<>();
        workStorePalletDOQueryWrapper.in("work_id",workIds);
        workStorePalletDOQueryWrapper.orderByDesc("id");
        workStorePalletDOQueryWrapper.groupBy("work_id");
        List<WorkStorePalletDO> workStorePalletDOS = workStorePalletMapper.selectList(workStorePalletDOQueryWrapper);

        QueryWrapper<WorkStoreDO> workStoreDOQueryWrapper = new QueryWrapper<>();
        workStoreDOQueryWrapper.in("work_id",workIds);
        workStoreDOQueryWrapper.orderByDesc("id");
        workStoreDOQueryWrapper.groupBy("work_id");
        List<WorkStoreDO> workStoreDOS = workStoreMapper.selectList(workStoreDOQueryWrapper);
        List<WorkOrderDO> workOrderDOS = workOrderMapper.selectList(new QueryWrapper<WorkOrderDO>().in("id",workIds));
        //结算金额
        BigDecimal totalPrice = new BigDecimal(0);
        //结算重量
        BigDecimal totalWeight = new BigDecimal(0);
        for (WorkSaleODODetailRespVO item:detailRespVOS) {
            BigDecimal perBoxNum = BigDecimal.valueOf(0L);

            for (WorkStorePalletDO workStorePalletDO:workStorePalletDOS) {
                if(item.getWorkId().equals(workStorePalletDO.getWorkId())){
                    perBoxNum = workStorePalletDO.getBoxNum();
                    break;
                }
            }
            for (WorkStoreDO workStoreDO:workStoreDOS) {
                if(item.getWorkId().equals(workStoreDO.getWorkId())){
                    item.setBatchNumber(workStoreDO.getBatchNumber());
                    break;
                }
            }
            for (WorkOrderDO order:workOrderDOS) {
                if(Long.valueOf(item.getWorkId()).equals(order.getId())){
                    item.setSpecification(order.getSpecification());
                    item.setProductName(order.getProductName());
                    item.setPerBoxNum(perBoxNum);
                    BigDecimal price = new BigDecimal(0);
                    if((order.getProductPrice()!=null&&!order.getProductPrice().equals(""))||order.getEstimatedUnitPrice()!=null){
                         price = order.getProductPrice()==null?order.getEstimatedUnitPrice():new BigDecimal(order.getProductPrice());
                    }

                    item.setProductPrice(String.valueOf(price));
                    int boxNum = 0;
                    if(order.getStorageMethod().equals("1")){
                        item.setQuantity(String.valueOf(item.getOutboundQuantity()));
                        boxNum = BigDecimal.valueOf(item.getOutboundQuantity()).divide(perBoxNum, 0, RoundingMode.CEILING).intValue();

                    }else{
                        item.setQuantity(String.valueOf(item.getOutboundWeight()));
                        boxNum = item.getOutboundWeight().divide(perBoxNum, 0, RoundingMode.CEILING).intValue();
                    }
                    item.setBoxNum(boxNum);
                    totalWeight = totalWeight.add(new BigDecimal(item.getQuantity()));
                    totalPrice = totalPrice.add(new BigDecimal(item.getQuantity()).multiply(price));
                    break;
                }
            }
        }
        data.setCustomerName(workOrderDOS.get(0).getCustomerName());
        data.setSupplierName(workOrderDOS.get(0).getSupplierName());
        Long dijiNum = 0L;
        QueryWrapper<WorkSaleOutboundDO> saleOutboundDOQueryWrapper = new QueryWrapper<>();
        saleOutboundDOQueryWrapper.eq("work_id",workOrderDOS.get(0).getWhiteItemsNum());
        if(workOrderDOS.get(0).getStorageMethod().equals("1")){
            YearMonth yearMonth = YearMonth.of(workOrderDOS.get(0).getCreateTime().getYear(), workOrderDOS.get(0).getCreateTime().getMonth());
            String startOfMonth = yearMonth.toString()+"-01 00:00:00"; // 该月的第一天的开始时间
            String endOfMonth = yearMonth.atEndOfMonth()+" 23:59:59"; // 该月的最后一天的结束时间

            saleOutboundDOQueryWrapper.ge("create_time",startOfMonth);
            saleOutboundDOQueryWrapper.le("create_time",endOfMonth);
            dijiNum = workSaleOutboundMapper.selectCount(saleOutboundDOQueryWrapper);
        }else{
            Year year = Year.of(workOrderDOS.get(0).getCreateTime().getYear());
            String yearStart = year.toString()+"-01-01 00:00";
            String yearEnd = year.toString()+"-12-31 23:59:59";
            saleOutboundDOQueryWrapper.ge("create_time",yearStart);
            saleOutboundDOQueryWrapper.le("create_time",yearEnd);
            dijiNum = workSaleOutboundMapper.selectCount(saleOutboundDOQueryWrapper);
        }

        Date now = new Date();
        String nowStr = FastDateFormat.getInstance("yyyy-MM-dd", TimeZone.getTimeZone("UTC")).format(now);
        data.setZdDate(nowStr);
        String year = String.valueOf(now.getYear());
        String month = String.valueOf(now.getMonth());
        data.setZlpjNumber(year+"-"+dijiNum);
        data.setSlpjNumber(month+"-"+dijiNum);
        data.setTotalWeight(totalWeight.toString());
        data.setTotalPrice(totalPrice.toString());
        data.setDetailRespVOS(detailRespVOS);

        return data;
    }

    @Override
    public PageResult<WorkSaleOutboundRespVO> getWorkSaleOutboundPage(WorkSaleOutboundPageReqVO pageReqVO) {
        PageResult<WorkSaleOutboundDO> arr = workSaleOutboundMapper.selectPage(pageReqVO);
        PageResult<WorkSaleOutboundRespVO> data = BeanUtils.toBean(arr, WorkSaleOutboundRespVO.class);
        List<Integer> workIds = new ArrayList<>();
        for (WorkSaleOutboundRespVO item:data.getList()) {
            workIds.add(item.getWorkId());
        }
        workIds.add(0);
        List<WorkOrderDO> workOrderDOS = workOrderMapper.selectList(new QueryWrapper<WorkOrderDO>().in("id",workIds));
        for (WorkSaleOutboundRespVO item:data.getList()) {
            for (WorkOrderDO order:workOrderDOS) {
                if(Long.valueOf(item.getWorkId()).equals(order.getId())){
                    item.setCustomerId(order.getCustomerId());
                    break;
                }
            }
        }
        return data;
    }

}
